package com.example.mytestdemo.car.media

import android.content.ComponentName
import android.content.Intent
import android.media.MediaMetadata
import android.media.browse.MediaBrowser
import android.media.session.MediaController
import android.media.session.PlaybackState
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.annotation.RequiresApi
import com.example.mytestdemo.BaseViewBindActivity
import com.example.mytestdemo.R
import com.example.mytestdemo.databinding.ActivityCarMainBinding
import com.example.mytestdemo.databinding.ActivityMediaSessionMainBinding

/**
 * @author tgw
 * @date 2022/9/13
 * @describe
 */
class CarMediaSessionActivity : BaseViewBindActivity<ActivityMediaSessionMainBinding>() {
    companion object {
        private const val TAG = "CarMediaSessionActivity"
    }

    private lateinit var mediaBrowser: MediaBrowser
    private var mMediaController: MediaController? = null

    override fun getLayoutInflateId(): Int {
        return R.layout.activity_media_session_main
    }

    override fun initData() {
        val component = ComponentName(this, MediaService::class.java)
        mediaBrowser = MediaBrowser(this, component, connectionCallback, null);
        mediaBrowser.connect()

    }

    override fun initUI() {
        mBind.btPlay.setOnClickListener {
            // 播放媒体
            mMediaController?.transportControls?.play()
        }

        mBind.btPause.setOnClickListener {
            // 播放媒体
            mMediaController?.transportControls?.pause()
        }

    }

    private val connectionCallback = object : MediaBrowser.ConnectionCallback() {
        @RequiresApi(Build.VERSION_CODES.M)
        override fun onConnected() {
            super.onConnected()
            Log.d(TAG, "ConnectionCallback onConnected: ")
            //媒体控制器，用来向服务端发送控制指令，例如：播放、暂停等等，在客户端中创建。
            // 媒体控制器是线 程安全的。MediaController还有一个关联的权限
            //android.permission.MEDIA_CONTENT_CONTROL（不是必须加的权限）必须是系统级应用才可以获
            //取，幸运的是车载应用一般都是系统级应用。
            //MediaController 必须在MediaBrowser连接成功后才可以创建
            if (mediaBrowser.isConnected) {
                val sessionToken = mediaBrowser.sessionToken
                mMediaController = MediaController(applicationContext, sessionToken)
                mMediaController?.registerCallback(controllerCallback)
            }

            //用于返回MediaBrowser.getItem()的结果。
            if (mediaBrowser?.isConnected) {
                // 获取根mediaId
                val mediaId = mediaBrowser?.root
                // 获取根mediaId的item列表，会触发MediaBrowserService.onLoadItem方法
                mediaBrowser?.getItem(mediaId, itemCallback)
            }
            // 用于订与MediaBrowserService中MediaBrowser.MediaItem列表变化的回调。
            if (mediaBrowser.isConnected) {
                val mediaId = mediaBrowser.root
                // 需要先取消订阅
                mediaBrowser.unsubscribe(mediaId)
                // 服务端会调用onLoadChildren
                // 订阅服务端 media item的改变，会触发 MediaBrowserService.onLoadChildren方法
                mediaBrowser.subscribe(mediaId, subscribeCallback)
            }


        }

        override fun onConnectionFailed() {
            super.onConnectionFailed()
            Log.d(TAG, "ConnectionCallback onConnectionFailed: ")
        }

        override fun onConnectionSuspended() {
            super.onConnectionSuspended()
            Log.d(TAG, "ConnectionCallback onConnectionSuspended: ")
        }
    }

    /**
     *用于订与MediaBrowserService中MediaBrowser.MediaItem列表变化的回调。
     */
    private val itemCallback = @RequiresApi(Build.VERSION_CODES.M)
    object : MediaBrowser.ItemCallback() {
        override fun onItemLoaded(item: MediaBrowser.MediaItem?) {
            super.onItemLoaded(item)
            Log.d(TAG, "ItemCallback onItemLoaded: ")
        }

        override fun onError(mediaId: String) {
            super.onError(mediaId)
            Log.d(TAG, "ItemCallback onError: ")
        }
    }


    private val subscribeCallback = object : MediaBrowser.SubscriptionCallback() {
        override fun onChildrenLoaded(
            parentId: String,
            children: MutableList<MediaBrowser.MediaItem>
        ) {
            super.onChildrenLoaded(parentId, children)
            Log.d(TAG, "SubscriptionCallback onChildrenLoaded: ")
        }

        override fun onChildrenLoaded(
            parentId: String,
            children: MutableList<MediaBrowser.MediaItem>,
            options: Bundle
        ) {
            super.onChildrenLoaded(parentId, children, options)
            Log.d(TAG, "SubscriptionCallback onChildrenLoaded: ")
        }

        override fun onError(parentId: String) {
            super.onError(parentId)
            Log.d(TAG, "SubscriptionCallback onError: ")
        }

        override fun onError(parentId: String, options: Bundle) {
            super.onError(parentId, options)
            Log.d(TAG, "SubscriptionCallback onError: ")
        }

    }


    private val controllerCallback = object : MediaController.Callback() {
        override fun onPlaybackStateChanged(state: PlaybackState?) {
            super.onPlaybackStateChanged(state)
            Log.d(TAG, "MediaController onPlaybackStateChanged: ")
            when (state?.state) {
                PlaybackState.STATE_PLAYING -> {
                // 处理UI
                }
                PlaybackState.STATE_PAUSED -> {
                // 处理UI
                }
                // 还有其它状态需要处理
            }

        }

        override fun onAudioInfoChanged(info: MediaController.PlaybackInfo?) {
            super.onAudioInfoChanged(info)
            Log.d(TAG, "MediaController onAudioInfoChanged: "+info?.currentVolume)
            val currentVolume = info?.currentVolume
// 显示在UI上
        }

        override fun onMetadataChanged(metadata: MediaMetadata?) {
            super.onMetadataChanged(metadata)
            val artUri =
                metadata?.getString(MediaMetadata.METADATA_KEY_ALBUM_ART_URI)
            Log.d(TAG, "MediaController onMetadataChanged: $artUri")
// 显示UI上
        }

        override fun onSessionEvent(event: String, extras: Bundle?) {
            super.onSessionEvent(event, extras)
            Log.d(TAG, "MediaController onSessionEvent: $event")
        }

        override fun onExtrasChanged(extras: Bundle?) {
            super.onExtrasChanged(extras)
            Log.d(TAG, "MediaController onExtrasChanged: ")
        }
    }
}